package com.common.sdk.net.download.dispatcher;

import java.io.File;
import java.util.Hashtable;
import java.util.concurrent.BlockingQueue;

import com.common.sdk.net.download.callback.CallbackObservable;
import com.common.sdk.net.download.callback.error.CallbackEnum;
import com.common.sdk.net.download.callback.error.DownloadState;
import com.common.sdk.net.download.db.ControlCacheAndDb;
import com.common.sdk.net.download.http.DownloadingNetwork;
import com.common.sdk.net.download.request.DownloadRequest;
import com.common.sdk.net.download.request.model.DownloadInfo;
import com.common.sdk.net.download.util.DownloadFilePathUtils;
import com.common.sdk.net.download.util.DownloadLog;
import com.common.sdk.net.connect.http.HttpStack;

/**
 * 单线程下载应用控制类
 * @author wenlonglv
 *
 */
public class DownloadAloneDispatcher extends com.common.sdk.net.download.dispatcher.BaseDispatcher {

    private HttpStack stack;
    File downloadFilePath = DownloadFilePathUtils.getDownloadFile();
    private BlockingQueue<DownloadInfo> downloadQueue;
    private Hashtable<String, DownloadInfo> absDownloadInfoTable;

    public DownloadAloneDispatcher(HttpStack stack, BlockingQueue<DownloadInfo> downloadQueue,
            Hashtable<String, DownloadInfo> absDownloadInfoTable) {
        this.stack = stack;
        this.downloadQueue = downloadQueue;
        this.absDownloadInfoTable = absDownloadInfoTable;

    }

    @Override
    public void run() {
        while (!isInterrupted() && !mQuit) {
            DownloadInfo downloadinfo = null;
            try {
                downloadinfo = downloadQueue.take();
                absDownloadInfoTable.put(downloadinfo.getKey(), downloadinfo);
                DownloadLog.debug("time downloadQueue.take()" + System.nanoTime());
            } catch (InterruptedException e) {
                DownloadLog.error(e);
                if (mQuit) {
                    return;
                }
                continue;
            }
            if (!(downloadinfo.isWaitDownload() || downloadinfo.isStartDownload())) {// TODO
                                                                                     // 有问题
                absDownloadInfoTable.remove(downloadinfo.getKey());
                continue;
            }
            try {
                CallbackObservable.getIntence().notifyObservers(CallbackEnum.WILL_START_DOWNLOAD_ITEM, downloadinfo);
                // 下载过程
                DownloadingNetwork downloadNetwork = new DownloadingNetwork(stack);
                DownloadRequest downloadRequest = new DownloadRequest(downloadinfo);

                int num = downloadNetwork.performRequest(downloadRequest);
                callbackObservable(num, downloadinfo);

            } catch (Exception | Error e) {
                DownloadLog.debug("DownloadAloneDispatcher run onException");
                CallbackObservable.getIntence().notifyObservers(DownloadState.NET_ERROR_DEFAULT_NET_FAILED,
                        CallbackEnum.FAILED_DOWNLOAD, downloadinfo);
                DownloadLog.error(e);
                if (mQuit) {
                    return;
                }
            } finally {
                absDownloadInfoTable.remove(downloadinfo.getKey());
            }
        }
    }

    @Override
    public void quit() {
        super.quit();
    }

    private void callbackObservable(int num, DownloadInfo downloadinfo) {
        switch (num) {
            case DownloadState.DOWNLOAD_THREAD_DELETY_SUCCESS:
                DownloadFilePathUtils.deleteFile(downloadinfo.getDownloadFilePath());
                ControlCacheAndDb.deleteDownloadItemInThread(downloadinfo);
                break;
            case DownloadState.DATABASE_ERROR_NO:
                DownloadFilePathUtils.deleteFile(downloadinfo.getDownloadFilePath());
                ControlCacheAndDb.deleteDownloadFile(downloadinfo);
                break;
            case DownloadState.DATABASE_ERROR_NO_FILE:
                ControlCacheAndDb.deleteDownloadMapItem(downloadinfo);
                break;
            case DownloadState.DOWNLOAD_SUCCESS:
                ControlCacheAndDb.beginDownload(downloadinfo);
                CallbackObservable.getIntence().notifyObservers(CallbackEnum.FINISHED_DOWNLOAD, downloadinfo);
                break;
            case DownloadState.DOWNLOAD_STOP_SUCCESS:
                CallbackObservable.getIntence().notifyObservers(CallbackEnum.DID_STOP_DOWNLOAD_ITEM, downloadinfo);
                break;
            case DownloadState.DOWNLOAD_PAUSE_SUCCESS:
                CallbackObservable.getIntence().notifyObservers(CallbackEnum.DID_PAUSE_DOWNLOAD_ITEM, downloadinfo);
                break;
            case DownloadState.DOWNLOAD_SILENCE_PAUSE_SUCCESS:
                ControlCacheAndDb.startSilenceDownloadItem(downloadinfo);
                CallbackObservable.getIntence().notifyObservers(CallbackEnum.DID_STOP_DOWNLOAD_ITEM, downloadinfo);
                break;
            default:// 所有的错误都是在这，stop应用
                downloadinfo.stopDownload();
                ControlCacheAndDb.beginDownload(downloadinfo);
                CallbackObservable.getIntence().notifyObservers(num, CallbackEnum.FAILED_DOWNLOAD, downloadinfo);
                break;
        }

    }
}
